package cuongnh.project.japanesediary.vocabulary.model;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

@Entity
@Table(name = "tbl_grammar")
public class Grammar extends AbstractModelObject{

	@Id
	@Column(name = "grammar_id")
	@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="grammar_seq")
	@SequenceGenerator(
			name="grammar_seq",
			sequenceName="grammar_sequence",
			allocationSize=1
		)
	private Long grammarId;

	@Column(name = "grammar", length = 30)
	private String grammar;
	
	@Column(name = "grammar_form", length = 100)
	private String grammarForm;

	@Column(name = "meaning_vietnamese", length = 1000)
	private String vnMeaning;

	@Column(name = "meaning_english", length = 1000)
	private String enMeaning;

	@Column(name = "meaning_japanese", length = 1000)
	private String jpMeaning;

	@Column(name = "usage_vietnamese", length = 1000)
	private String vnUsage;

	@Column(name = "usage_english", length = 1000)
	private String enUsage;

	@Column(name = "usage_japanese", length = 1000)
	private String jpUsage;

	@ManyToMany(mappedBy = "grammars")
	private Set<Vocabulary> vocabularies = new HashSet<Vocabulary>();

	@ManyToMany(cascade = { CascadeType.ALL }, fetch=FetchType.LAZY)
	@JoinTable(name = "tbl_grammar_sentence", joinColumns = { @JoinColumn(name = "grammar_id") }, inverseJoinColumns = { @JoinColumn(name = "sentence_id") })
	private Set<Sentence> grammarExamples = new HashSet<Sentence>();
	
	@ManyToMany(cascade={CascadeType.ALL}, fetch = FetchType.LAZY)
	@JoinTable(name = "tbl_grammar_related", joinColumns = { @JoinColumn(name = "grammar_id") }, inverseJoinColumns = { @JoinColumn(name = "grammar_related_id") })
	private Set<Grammar> relatedsGrammar = new HashSet<Grammar>();

	@ManyToMany(mappedBy = "relatedsGrammar")
	private Set<Grammar> grammarRelateds = new HashSet<Grammar>();
	
	@ManyToMany(fetch = FetchType.LAZY)
	@JoinTable(name = "tbl_grammar_category", joinColumns = { @JoinColumn(name = "grammar_id") }, inverseJoinColumns = { @JoinColumn(name = "category_id") })
	private Set<Category> grammarCategories = new HashSet<Category>();
	
	@ManyToMany(cascade={CascadeType.ALL}, fetch = FetchType.LAZY)
	@JoinTable(name = "tbl_grammar_synonym", joinColumns = { @JoinColumn(name = "grammar_id") }, inverseJoinColumns = { @JoinColumn(name = "grammar_synonym_id") })
	private Set<Grammar> grammarSynonyms = new HashSet<Grammar>();

	@ManyToMany(mappedBy = "grammarSynonyms")
	private Set<Grammar> synonyms = new HashSet<Grammar>();

	@ManyToMany(cascade={CascadeType.ALL}, fetch = FetchType.LAZY)
	@JoinTable(name = "tbl_grammar_antonym", joinColumns = { @JoinColumn(name = "grammar_id") }, inverseJoinColumns = { @JoinColumn(name = "grammar_antonym_id") })
	private Set<Grammar> grammarAntonyms = new HashSet<Grammar>();

	@ManyToMany(mappedBy = "grammarSynonyms")
	private Set<Grammar> antonyms = new HashSet<Grammar>();
	
	@ManyToMany(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY)
	@JoinTable(name = "tbl_grammar_kanji", joinColumns = { @JoinColumn(name = "grammar_id") }, inverseJoinColumns = { @JoinColumn(name = "text_id") })
	private Set<Text> grammarTexts = new HashSet<Text>();
	
	@Column(name = "created_date")
	private Date createdDate;

	@Column(name = "modified_date")
	private Date modifiedDate;

	public long getGrammarId() {
		return grammarId;
	}

	public void setGrammarId(long grammarId) {
		this.grammarId = grammarId;
	}

	public String getGrammar() {
		return grammar;
	}

	public void setGrammar(String grammar) {
		this.grammar = grammar;
	}
	
	public String getGrammarForm() {
		return grammarForm;
	}

	public void setGrammarForm(String grammarForm) {
		this.grammarForm = grammarForm;
	}

	public String getVnMeaning() {
		return vnMeaning;
	}

	public void setVnMeaning(String vnMeaning) {
		this.vnMeaning = vnMeaning;
	}

	public String getEnMeaning() {
		return enMeaning;
	}

	public void setEnMeaning(String enMeaning) {
		this.enMeaning = enMeaning;
	}

	public String getJpMeaning() {
		return jpMeaning;
	}

	public void setJpMeaning(String jpMeaning) {
		this.jpMeaning = jpMeaning;
	}

	public String getVnUsage() {
		return vnUsage;
	}

	public void setVnUsage(String vnUsage) {
		this.vnUsage = vnUsage;
	}

	public String getEnUsage() {
		return enUsage;
	}

	public void setEnUsage(String enUsage) {
		this.enUsage = enUsage;
	}

	public String getJpUsage() {
		return jpUsage;
	}

	public void setJpUsage(String jpUsage) {
		this.jpUsage = jpUsage;
	}

	public Set<Vocabulary> getVocabularies() {
		return vocabularies;
	}

	public void setVocabularies(Set<Vocabulary> vocabularies) {
		this.vocabularies = vocabularies;
	}

	public Set<Sentence> getGrammarExamples() {
		return grammarExamples;
	}

	public void setGrammarExamples(Set<Sentence> grammarExamples) {
		Set<Sentence> oldValue = this.grammarExamples;
		this.grammarExamples = grammarExamples;
		firePropertyChange("vocabularyExamples", oldValue, grammarExamples);
	}

	public Set<Grammar> getRelatedsGrammar() {
		return relatedsGrammar;
	}

	public void setRelatedsGrammar(Set<Grammar> relatedsGrammar) {
		Set<Grammar> oldValue = this.relatedsGrammar;
		this.relatedsGrammar = relatedsGrammar;
		firePropertyChange("vocabularyExamples", oldValue, relatedsGrammar);		
	}

	public Set<Grammar> getGrammarRelateds() {
		return grammarRelateds;
	}

	public void setGrammarRelateds(Set<Grammar> grammarRelateds) {
		Set<Grammar> oldValue = this.grammarRelateds;
		this.grammarRelateds = grammarRelateds;
		firePropertyChange("vocabularyExamples", oldValue, grammarRelateds);
	}

	public Set<Category> getGrammarCategories() {
		return grammarCategories;
	}

	public void setGrammarCategories(Set<Category> grammarCategories) {
		Set<Category> oldValue = this.grammarCategories;
		this.grammarCategories = grammarCategories;
		firePropertyChange("grammarCategories", oldValue, grammarCategories);		
	}

	public Set<Grammar> getGrammarSynonyms() {
		return grammarSynonyms;
	}

	public void setGrammarSynonyms(Set<Grammar> grammarSynonyms) {
		this.grammarSynonyms = grammarSynonyms;
	}

	public Set<Grammar> getSynonyms() {
		return synonyms;
	}

	public void setSynonyms(Set<Grammar> synonyms) {
		this.synonyms = synonyms;
	}

	public Set<Grammar> getGrammarAntonyms() {
		return grammarAntonyms;
	}

	public void setGrammarAntonyms(Set<Grammar> grammarAntonyms) {
		this.grammarAntonyms = grammarAntonyms;
	}

	public Set<Grammar> getAntonyms() {
		return antonyms;
	}

	public void setAntonyms(Set<Grammar> antonyms) {
		this.antonyms = antonyms;
	}
	
	public Set<Text> getGrammarTexts() {
		return grammarTexts;
	}

	public void setGrammarTexts(Set<Text> grammarTexts) {
		Set<Text> oldValue = this.grammarTexts;
		this.grammarTexts = grammarTexts;
		firePropertyChange("grammarTexts", oldValue,
				grammarTexts);		
	}

	public void setGrammarId(Long grammarId) {
		this.grammarId = grammarId;
	}

	public Date getCreatedDate() {
		return createdDate;
	}

	public void setCreatedDate(Date createdDate) {
		this.createdDate = createdDate;
	}

	public Date getModifiedDate() {
		return modifiedDate;
	}

	public void setModifiedDate(Date modifiedDate) {
		this.modifiedDate = modifiedDate;
	}

	@Override
	public boolean equals(Object obj) {
		boolean sameSame = false;

		if (obj != null && obj instanceof Grammar) {
			sameSame = grammarId.equals(((Grammar) obj).grammarId);
		}

		return sameSame;
	}
	
	@Override
	public int hashCode() {
		return this.grammarId.intValue();
	}
}
